App.require(["canvasTool"], function (canvasTool) {
    var app = App.getCurrent();

    app.defineLayer("str-layer", {
        render: function (next) {
            this.initProperty();
            this.data.isChange = true;
            this.fetch("./index.html", function (text) {
                next(this.renderHTML(text));
            })
        },
        initProperty: function () {
            var property = this.property;
            property.id = property.id || this.uid;

            this.data.attributeStr = this._createPropertyStr(property);
            
            this.data.isMouseIn = false;
            if (property.animation) this.addPropertyAnimation(property.animation, this);
        },
        init: function () {
            this.data.canvas = document.createElement("canvas");
        },
        dispose: function () {
            this.removeAnimation();
            this.data.canvas = null;
            this.data.isChange = true;
            this.data.isMouseIn = false;
        },
        _changeBackObj: function (str, ratio) {
            if (str.indexOf("#") == 0) {
                var pattern = /\#(\S+)\s*([\s\S]*)/;
                var matches = pattern.exec(str);
                if (matches[2]) {
                    var list = matches[2].split(/\s+/).map(function (item) {
                        return parseInt(item);
                    });
                    return {
                        id: matches[1],
                        left: list[0] * ratio,
                        top: list[1] * ratio,
                        width: list[2] * ratio,
                        height: list[3] * ratio
                    }
                }
                return {
                    id: matches[1]
                };
            }
            return false;
        },
        draw: function (ctx, ratio) {
            if (this.hidden || !this.data.canvas) return;
            var canvas = this.data.canvas;
            if (this._getChange()) {
                canvas.width = this.width * ratio;
                canvas.height = this.height * ratio;
                var context = canvas.getContext("2d");
                context.clearRect(0, 0, canvas.width, canvas.height)
                var components = this.components;
                for (var i = 0; i < components.length; i++) {
                    var com = components[i];
                    if (typeof com.draw === "function") com.draw(context, ratio);
                }
            }
            ctx.save();
            var dObj = this.getPropertyUse(["opacity", "x", "y", "shadow"]);
            if (typeof dObj.opacity !== "undefined") ctx.globalAlpha = parseFloat(dObj.opacity);
            if (this.background) {
                var bObj = this._changeBackObj(this.background, ratio);
                if (bObj && bObj.id) {
                    var parentCanvas = this._getCanvas();
                    var component = parentCanvas.getComponentById(bObj.id);
                    if (component) {
                        var bkCanvas = component._draw(ratio);
                        var left = bObj.left || dObj.x,
                            top = bObj.left || dObj.y,
                            width = bObj.width || this.width,
                            height = bObj.height || this.height;

                        ctx.drawImage(bkCanvas, left * ratio, top * ratio, width * ratio, height * ratio, left * ratio, top * ratio, width * ratio, height * ratio);
                    }
                }
            }
            this.transformView(ctx, ratio);
            if (dObj.shadow) this.useShadow(ctx, dObj.shadow, ratio);
            var w = this.width * ratio, h = this.height * ratio;
            ctx.beginPath();
            ctx.rect(0, 0, w, h);
            ctx.clip();
            ctx.drawImage(canvas, 0, 0);
            ctx.restore();
            this.data.isChange = false;
        },
        createPath: function (ctx, ratio) {
            var w = this.width * ratio, h = this.height * ratio;
            ctx.beginPath();
            ctx.rect(0, 0, w, h);
        },
        moveLayerHandler: function (ev, ctx, ratio) {
            if (this.containsBounds(ctx, ev.clientX, ev.clientY, ratio)) {
                if (!this.data.isMouseIn) {
                    this.data.isMouseIn = true;
                    this.dispatchCustomEvent("layermouseenter", {
                        component: this,
                        event: ev
                    });
                }
            } else {
                if (this.data.isMouseIn) {
                    this.data.isMouseIn = false;
                    this.dispatchCustomEvent("layermouseleave", {
                        component: this,
                        event: ev
                    });
                }
            }
        },
        transformView: function (ctx, ratio) {
            ratio = ratio || 1;
            ctx.translate(this.x * ratio, this.y * ratio);
            var obj = this.getPropertyUse(["transform"]);
            if (obj.transform) {
                var tList = obj.transform;
                for (var i = 0; i < tList.length; i++) {
                    var tObj = tList[i];
                    if (tObj.action == "translate") {
                        ctx.translate(tObj.args[0] * ratio, tObj.args[1] * ratio);
                    }
                    else {
                        ctx[tObj.action].apply(ctx, tObj.args);
                    }
                    
                }
            }
        },
        clickLayerHandler: function (ev, ctx, ratio) {
            if (this.containsBounds(ctx, ev.clientX, ev.clientY * ratio)) {
                this.dispatchCustomEvent("layerclick", {
                    component: this,
                    event: ev
                });
            }
        },
        set hidden(value) {
            this.setValue("hidden", value);
        },
        get hidden() {
            return this.getValue("hidden");
        },
        set background(value) {
            this.setValue("background", value);
        },
        get background() {
            return this.getValue("background");
        },
        get transform() {
            return this.getValue("transform");
        },
        set transform(value) {
            this.setValue("transform", value);
        },
        get shadow() {
            return this.getValue("shadow");
        },
        set shadow(value) {
            this.setValue("shadow", value);
        },
        get x() {
            return this.getValue("x");
        },
        set x(value) {
            this.setValue("x", value);
        },
        get y() {
            return this.getValue("y");
        },
        set y(value) {
            this.setValue("y", value);
        },
        get width() {
            return this.getValue("width");
        },
        set width(value) {
            this.setValue("width", value);
        },
        get height() {
            return this.getValue("height");
        },
        set height(value) {
            this.setValue("height", value);
        },
        set opacity(value) {
            this.setValue("opacity", value);
        },
        get opacity() {
            return this.getValue("opacity");
        },
        get animation() {
            return this.getValue("animation");
        },
        set animation(value) {
            if (this.setValue("animation", value)) {
                if (value) this.addPropertyAnimation(value, this);
            }
        },
        set transition(value) {
            this.setValue("transition", value);
        },
        get transition() {
            return this.getValue("transition");
        }
    })
})